package main

import (
	"fmt"
	"gitee.com/zhongguo168a/go-nodex/dbx/mongox"
	"gitee.com/zhongguo168a/go-nodex/nodex"
	"gitee.com/zhongguo168a/go-nodex/nodex/client"
	"gitee.com/zhongguo168a/go-nodex/nodex/models"
	"gitee.com/zhongguo168a/go-nodex/nodex/server/http"
	"gitee.com/zhongguo168a/go-nodex/nodex/server/tcp"
	"gitee.com/zhongguo168a/go-nodex/nodex/server/ws"
	"gitee.com/zhongguo168a/gocodes/gox/osx/signalx"
	"gitee.com/zhongguo168a/gocodes/myx/errorx"
	"github.com/pkg/errors"
	"reflect"
	"time"
)

func main() {
	count := 0
	nodeConfig := &nodex.NodeConfig{
		Name: "example",
		PreServe: func() (err error) {
			return
		},
		Database: &mongox.Database{
			Name:   "nodex",
			Prefix: "example_",
			Addrs: []*mongox.Addr{
				{IP: "www.mywork.com", Port: "27017", User: "root", Pwd: "lJ3fB7vH2eW2iJ2e"},
			},
		},
		MsgQueue: &nodex.NsqMsgQueue{
			ProducerAddr: "mywork.com:4150",
			LookupdAddr:  "mywork.com:4161",
		},
		Channel:       "test",
		SerializeMode: nodex.JSON,
		Servers: []*models.ServerConfig{
			{
				Name: "tcp",
				Host: "127.0.0.1",
				Port: "2001",
				Mode: tcp.NAME,
			},
			{
				Name: "ws",
				Host: "127.0.0.1",
				Port: "2000",
				Mode: ws.NAME,
			},
			{
				Name: "http",
				Host: "127.0.0.1",
				Port: "8082",
				Mode: http.NAME,
			},
		},
		ChanRPCSelectors: map[string]nodex.ChanRPCSelector{
			"player": func(ctx nodex.IContext, route *nodex.Router) (rpckey string, err error) {
				// 从链接的上下文中，获取Token
				itoken, has := ctx.GetConnection().GetProperty().Load("Token")
				if has == false {
					return "", errors.New("token not found")
				}
				token := itoken.(string)
				// 消息会发送到编号为[rpckey]的 chanrpc
				rpckey = "player" + token
				return
			},
		},
		//ContextCreators: map[string]nodez.ContextCreator{
		//	"sample_context": func(ctx nodez.IContext) (newctx nodez.IContext, err error) {
		//		last := ctx.(*nodez.Context)
		//		ictx, cancel := context.WithTimeout(ctx, time.Second*3)
		//		defer cancel()
		//
		//		last.Context = ictx
		//		return last, nil
		//	},
		//	"player_context": func(ctx nodez.IContext) (newctx nodez.IContext, err error) {
		//		last := ctx.(*nodez.Context)
		//		ictx, cancel := context.WithTimeout(ctx, time.Second*3)
		//		defer cancel()
		//
		//		last.Context = ictx
		//		return last, nil
		//	},
		//},
		Routes: []*nodex.RouterConfig{
			{
				AtServers: []string{ws.NAME, http.NAME, tcp.NAME},
				Path:      "user/Login",
				Handler: reflect.ValueOf(func(ctx nodex.IContext, args *Args, reply *Reply) (err error) {
					count++
					fmt.Println(count, "user/Login", args)
					ctx.GetNode().CreateChanRPC("player", "111")
					return nil
				}),
			},
			//{
			//	AtServers: []string{"http"},
			//	Name:      "user/Echo",
			//	Handler: reflect.ValueOf(func(ctx nodex.IContext, args *Args) {
			//		htthctx := ctx.GetRequest().GetHttpContext()
			//
			//		htthctx.String(http.StatusOK, htthctx.Request.URL.Query().Get("msg"))
			//		return
			//	}),
			//},
		},
		RouteGroup: []*nodex.RouteGroupConfig{
			{
				AtServers:    []string{tcp.NAME},
				Name:         "user/test",
				RouteHandler: &RouteGroup{},
			},
			//{
			//	AtGates:           []string{"ws"},
			//	Name:              "player.basic",
			//	UseRPCSelector:    "rpc_selector_player",
			//	UseContextCreator: "client_context",
			//	RouteHandler:      &basicz.Service{},
			//},
			//{
			//	AtServers: []string{"ws", "http"},
			//	Name:      "editor",
			//	//RouteHandler:  &editor.Service{},
			//	EnableHttpGet: true,
			//},
		},
	}

	node := nodex.Init(nodeConfig)
	runerr := node.Run()
	if runerr != nil {
		fmt.Println(runerr)
		return
	}

	go func() {
		time.Sleep(time.Second)
		for i := 0; i < 100; i++ {
			c, err := client.GetClient("127.0.0.1:2001")
			if err != nil {
				err = errorx.Wrap(err, fmt.Sprintf("dial"))
				return
			}
			_ = c
			err = c.Call("user/test/Method1", &Args{}, &Reply{})
			if err != nil {
				fmt.Println(errors.Wrap(err, fmt.Sprintf("call")))
				continue
			}
			fmt.Println(i, "succeed")

			c.Close()
		}

	}()

	signalx.WaitSignal(nil)
}

type Args struct {
}
type Reply struct {
}

type RouteGroup struct{}

func (rg *RouteGroup) NZInit() (err error) {
	return
}

func (rg *RouteGroup) Method1(ctx nodex.IContext, args *Args, reply *Reply) (err error) {
	fmt.Println("RouteGroup.Method1")
	return
}
